#include "Round.h"
#include "Hand.h"
#include "UI.h"
#include "RS232.h"

unsigned char
round_play(Stack *stack)
{
  Hand player_hand, dealer_hand;
  unsigned char player_score, dealer_score, i;

  // Clear hands
  hand_clear(&player_hand);
  hand_clear(&dealer_hand);

  // Deal first card to player
  player_hand[0] = stack_next_card(stack);
  // Deal first card to dealer
  dealer_hand[0] = stack_next_card(stack);
  // Deal second card to player
  player_hand[1] = stack_next_card(stack);
  // Deal second card to dealer
  dealer_hand[1] = stack_next_card(stack);

  // Calculate scores
  player_score = hand_get_score(&player_hand);
  dealer_score = hand_get_score(&dealer_hand);

  // Update card counting clients
  rs232_card_dealt(player_hand[0]);
  rs232_card_dealt(dealer_hand[0]);
  rs232_card_dealt(player_hand[1]);

  // Check for player blackjack (player = 21)
  if (player_score == 21) {
    rs232_card_dealt(dealer_hand[1]);

    // Check for double blackjack (player = 21 and dealer = 21)
    if (dealer_score == 21) {
      // Nobody wins
      ui_round_result(&player_hand, &dealer_hand, 1);
      return 1;
    }

    // Player instantly wins
    ui_round_result(&player_hand, &dealer_hand, 2);
    return 2;
  }

  // While player score is below 21
  i = 2;
  do {
    // .. ask player if he wants to hit or stand
    unsigned char hit = ui_hit_or_stand(&player_hand, &dealer_hand);

    // If player wants to be hit
    if (hit) {
      // .. deal another card
      player_hand[i] = stack_next_card(stack);
      rs232_card_dealt(player_hand[i]);
      i++;
    } else {
      // .. otherwise stand
      break;
    }

    player_score = hand_get_score(&player_hand);

    // Check for five card instant win
    if (i == 5 && player_score < 21) {
      // Player wins
      rs232_card_dealt(dealer_hand[1]);
      ui_round_result(&player_hand, &dealer_hand, 2);
      return 2;
    }
  } while (player_score < 21);

  // Check if player is busted
  if (player_score > 21) {
    rs232_card_dealt(dealer_hand[1]);
    ui_round_result(&player_hand, &dealer_hand, 0);
    return 0;
  }

  // While dealer score is below 21 and below player score
  i = 2;
  while (dealer_score < 21 && dealer_score < player_score) {
    // .. deal another card
    dealer_hand[i] = stack_next_card(stack);
    rs232_card_dealt(dealer_hand[i]);
    i++;

    dealer_score = hand_get_score(&dealer_hand);

    // Check for five card instant win
    if (i == 5 && dealer_score < 21) {
      // Dealer wins
      rs232_card_dealt(dealer_hand[1]);
      ui_round_result(&player_hand, &dealer_hand, 0);
      return 0;
    }
  }

  // If dealer score is greater than 21
  rs232_card_dealt(dealer_hand[1]);
  if (dealer_score > 21) {
    // .. Player wins
    ui_round_result(&player_hand, &dealer_hand, 2);
    return 2;
  } else {
    // .. otherwise Dealer wins
    ui_round_result(&player_hand, &dealer_hand, 0);
    return 0;
  }
}
